module Input.InputRecorder;
private import Input.GamePad;
//private import Imput.KeyCode;
private import std.string;
//private import std.stdio;
//private import std.metastrings;
//private import std.format;
private import System.Console;
/*
private import std.file;
private import std.path;
private import std.cstream;
private import std.ctype;
private import std.math;
private import std.math2;
private import std.c.stdio;
private import std.utf;
private import std.random;
*/

public class InputRecorder{
	private static const int CR = 50; // 改行位置
	private static const int SHIFT = 0x3b;

	private int _cnt = 0;
	private bool _hasNext = false;
	public  bool hasNext(){return _hasNext;}
	public  int  length(){return _cnt;}
	private char[] _data; // StringBuffer

	public this() {
		_data = "";
	} //
	public void reset(){
		_cnt = 0;
		_hasNext = false;
		_data = "";
	} //

	public int  record( IGamePad pad ){
		int s = pad.padStatus;
		_data ~= cast(int)s + SHIFT;
		_cnt++;
		return s;
	} //
	public int play( IGamePad pad ){
		if( !_hasNext ) return pad.padStatus;
		int t = cast(int)(_data[ _cnt++ ] ) - SHIFT;
		_hasNext = ( _data.length > _cnt ) ? true : false;
	 return t;
	} //

	protected char[] itoa(int c){
		return std.string.toString( c );
	} //

	public char[]  data(){
		char[] dt = "0" ~ _data;//.insert(0,'0');

		char[] tmp = "";
		int i = 0 , chk1 = cast(int)dt[1], chk2 = 0, cnt = 0;
		
		for ( int len = dt.length - 1 ; i <  len ; i++ ) {
			chk2 = cast(int)( dt[i+1] ); //.charCodeAt( i + 1 );
			if ( chk1 != chk2 ) {// || cnt >= 255){
				if (cnt > 1)
					tmp ~= cast(char)chk1 ~ itoa( cnt );
				else{
					tmp ~= cast(char)chk1;
				}
				cnt  = 1;
				chk1 = chk2;
			}else
				cnt++;
		}
		tmp ~= cast(char)chk1 ~ itoa( cnt );


		char[] tmp2 = "";
		for ( i = 0 ; i < tmp.length ; i += CR ) {
			int crr = i + CR;
			if( crr > tmp.length ) crr = tmp.length;
			for ( int j = i ; j < crr ; j++ ) tmp2 ~= tmp[j];
			tmp2 ~= "\n";
		}
		return tmp2;
	} //

	public void data( char[] code ){
		_data = "";//.setLength(0);
		_data ~= decompress( code );
		_hasNext = true;
		_cnt = 0;
	} //

	public char[]  decompress( char[] txt ){
		char[] tmp = "";
		char[] len = "";
		int current = 0;
		// abcd3e5c6 → abcdddeeeeecccccc
		int Yn = cast(int)'\n';
		int Yr = cast(int)'\r';
		int Yt = cast(int)'\t';
		int Ys = cast(int)' ';
		int c0 = cast(int)'0';
		int c9 = cast(int)'9';

		for ( int i = 0 , l = txt.length ; i < l ; i++ ) {
			int c = cast( int )( txt[i] );

			if ( c == Yn || c == Yr || c == Yt || c == Ys ) continue;

			if ( ( c >= 0x40 && c <= 0xff ) || ( c >= 0x100 && c <= 0x140 ) ) {
				if( len.length > 0 ){
					int clen  = cast(int)atoi( len ) -1;
					for( int j = 0 ; j < clen ; j++ )tmp ~= cast(char)current;//String.fromCharCode(current);
				}
				current = c;
				tmp ~=  cast(char)c; //String.fromCharCode( c ) ;
				len = "";
			} else
			if ( c >= c0 && c<= c9 ) {
				len ~=  cast(char)c; //String.fromCharCode( c ) ;
			}

		}
		if ( len.length > 0) {
			int clen2 = cast(int)atoi( len ) -1;
			for( int k = 0 ; k < clen2 ; k++ ) tmp ~= cast(char)current;//String.fromCharCode( current ) ;
		}
//		Console.write( "decompress:\nbifore:" ~ txt ~ "\nafter:" ~ tmp);
		return tmp;
	} //

	public void cut( int len ) {
		_data.length = len;
	} //

} //


